﻿// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Globalization;
using System.Fabric.Description;
using System.Diagnostics.Contracts;

namespace ActorRuntimeManager
{
    public partial class DeployAppForm : Form
    {
        private string m_connectionString;
        private string m_imageStoreExeFileName;

        private static string s_appBase = Environment.CurrentDirectory + "\\" + @"ActorManifest\ApplicationPackages";

        public DeployAppForm(string[] candidates, string connectionString, string fileName)
        {
            Contract.Requires(candidates != null);
            m_connectionString = connectionString;
            m_imageStoreExeFileName = fileName;

            InitializeComponent();

            this.buttonDeploy.Enabled = false;
            foreach (var candidate in candidates)
            {
                this.comboBoxCandidates.Items.Add(candidate);
            }
        }

        private void comboBoxCandidates_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.buttonDeploy.Enabled = true;
        }

        private void buttonDeploy_Click(object sender, EventArgs e)
        {
            string selectedActorApp = (string)comboBoxCandidates.SelectedItem;
            string sourceFolder = s_appBase + "\\" + selectedActorApp;
            string relativeDestPath = "incoming\\" + selectedActorApp;

            var imageStoreArgs = String.Format(CultureInfo.InvariantCulture, @"Upload -c ""{0}"" -x ""{1}"" -l ""{2}"" -g AtomicCopy", m_connectionString, relativeDestPath, sourceFolder);
            var p1 = Process.Start(m_imageStoreExeFileName, imageStoreArgs);

            p1.WaitForExit();
            //var status = String.Format("Upload exit code = {0}, exe = {1}, args = {2}", p1.ExitCode, m_imageStoreExeFileName, imageStoreArgs);
            //MessageBox.Show(status);
            if (p1.ExitCode == 0)
            {
                this.labelStatus.Text = "Upload succeeded.  Provisioning...";
            }
            else
            {
                MessageBox.Show("Upload Failed!  Aborting");
                Close();
                return;
            }

            // Unprovision if necessary
            try
            {
                MainForm.Client.ApplicationManager.UnprovisionApplicationAsync(selectedActorApp,"1.0").Wait();
                //MessageBox.Show("(Unprovisioning succeeded)");
            }
            catch (Exception)
            {
            }

            try
            {
                MainForm.Client.ApplicationManager.ProvisionApplicationAsync(relativeDestPath).Wait();
                this.labelStatus.Text = "Provisioning succeeded.  Starting...";
            }
            catch (Exception exc)
            {
                Exception baseException = (exc is AggregateException) ? ((AggregateException)exc).GetBaseException() : exc;
                MessageBox.Show("Exception from Provisioning: " + baseException);
                Close();
                return;
            }

            var appName = MainForm.FabricAppNameFromAppName(selectedActorApp);
            Contract.Assume(appName != null, "Made the assumption explicit. FabricAppNameFromAppName may return null, from its code");
            var version = "1.0";

            try
            {
                MainForm.Client.ApplicationManager.CreateApplicationAsync(new ApplicationDescription(new Uri(appName), selectedActorApp, version)).Wait();
            }
            catch (Exception exc)
            {
                Exception baseException = (exc is AggregateException) ? ((AggregateException)exc).GetBaseException() : exc;
                MessageBox.Show("Exception from Application Creation: " + baseException);
                Close();
            }

            Close();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}
